import storage from "store";
import { MutationTypes } from "./mutation-types";
import { PlayerInfo, PlayerProperty, RemovePackItemMulty } from "./types";
import { RootState } from "../types";
import { objEncodeToStr, strDecodeToObj } from "@/util/util";
import { initUserInfo, initUserProperty } from "./state";
import { Equipment } from "@/const/equips/equipmentType";
import { PackItemDTO } from "@/const/Entity";
import { db, LocalStorage } from "@/Indexed/appdb";

export type Mutations<S = RootState> = {
  [MutationTypes.SET_USER_INFO](state: S, payload: PlayerInfo): void;
  [MutationTypes.GET_USER_INFO](state: S): PlayerInfo;
  [MutationTypes.CLEAR_USER_INFO](state: S): void;
  [MutationTypes.MIGRATION_USER_INFO](state: S): void;
  [MutationTypes.MAKE_MONEY](state: S, payload: number): void;
  [MutationTypes.COST_MONEY](state: S, payload: number): void;
  [MutationTypes.SET_USER_PROPERTY](state: S, payload: PlayerProperty): void;
  [MutationTypes.GET_USER_PROPERTY](state: S): void;
  [MutationTypes.SET_CURRENT_HP](state: S, payload: number): void;
  [MutationTypes.PUT_ITEM_TO_PACKAGE](state: S, payload: PackItem): void;
  [MutationTypes.REMOVE_ITEM_TO_PACKAGE](state: S, payload: number): void;
  [MutationTypes.REMOVE_ITEM_TO_PACKAGE_MUL](
    state: S,
    payload: RemovePackItemMulty[]
  ): void;
  [MutationTypes.GET_PACKAGE](state: S): void;
  [MutationTypes.GET_EQUIP](state: S): void;
  [MutationTypes.WEAR_EQUIP](state: S, payload: Equipment): void;
  [MutationTypes.CAST_EQUIP](state: S, payload: Equipment): void;
  [MutationTypes.SET_TOWER_LEVEL](state: S, payload: any): void;
  [MutationTypes.GET_TOWER_LEVEL](state: S): void;
  [MutationTypes.SET_USER_STATE](state: S, payload: number): void;
  [MutationTypes.TIDY_PACKAGE](state: S): void;
};

export const playerMutations: Mutations = {
  [MutationTypes.SET_USER_INFO](state, payload) {
    // 设置为已登录状态
    payload.isLogin = true;
    state.userInfo = payload;
    const storeData = objEncodeToStr(state.userInfo);
    storage.set(MutationTypes.SET_USER_INFO, storeData);
  },
  [MutationTypes.CLEAR_USER_INFO](state) {
    state.userInfo = initUserInfo();
    const storeData = objEncodeToStr(state.userInfo);
    storage.set(MutationTypes.SET_USER_INFO, storeData);
  },
  [MutationTypes.GET_USER_INFO](state) {
    const storeData = storage.get(
      MutationTypes.SET_USER_INFO,
      objEncodeToStr(initUserInfo())
    );
    const payload = strDecodeToObj(storeData);
    if (payload.state === 2) {
      payload.state = 0;
    }
    state.userInfo = payload;
    return state.userInfo;
  },
  [MutationTypes.MIGRATION_USER_INFO]() {
    const storeData = storage.get(
      MutationTypes.SET_USER_INFO,
      objEncodeToStr(initUserInfo())
    );
    // 此版本开始同步IndexedDb
    db.userInfo?.add(new LocalStorage(storeData));
  },
  [MutationTypes.MAKE_MONEY](state, payload) {
    state.userInfo.money += payload;
    const storeData = objEncodeToStr(state.userInfo);
    storage.set(MutationTypes.SET_USER_INFO, storeData);
  },
  [MutationTypes.COST_MONEY](state, payload) {
    state.userInfo.money -= payload;
    const storeData = objEncodeToStr(state.userInfo);
    storage.set(MutationTypes.SET_USER_INFO, storeData);
  },
  [MutationTypes.SET_USER_PROPERTY](state, payload) {
    state.userProperty = payload;
    const storeData = objEncodeToStr(state.userProperty);
    storage.set(MutationTypes.SET_USER_PROPERTY, storeData);
  },
  [MutationTypes.GET_USER_PROPERTY](state) {
    const storeData = storage.get(
      MutationTypes.SET_USER_PROPERTY,
      objEncodeToStr(initUserProperty())
    );
    const payload = strDecodeToObj(storeData);
    state.userProperty = payload;
  },
  [MutationTypes.SET_CURRENT_HP](state, payload) {
    state.userProperty.CHP = payload;
    const storeData = objEncodeToStr(state.userProperty);
    storage.set(MutationTypes.SET_USER_PROPERTY, storeData);
  },
  [MutationTypes.PUT_ITEM_TO_PACKAGE](state, payload) {
    const userPackage = [...state.userPackage];
    const idx = userPackage.findIndex(m => m.id === payload.id);
    if (idx >= 0) {
      // 存在
      userPackage[idx].count += payload.count;
    } else {
      // 不存在
      userPackage.push(payload);
    }
    state.userPackage = userPackage;
    const storeData = objEncodeToStr(userPackage);
    storage.set(MutationTypes.PUT_ITEM_TO_PACKAGE, storeData);
  },
  [MutationTypes.REMOVE_ITEM_TO_PACKAGE](state, payload) {
    const userPackage = [...state.userPackage];
    const idx = userPackage.findIndex(m => m.id === payload);
    if (idx >= 0) {
      // 存在
      if (userPackage[idx].type === "equipment") {
        state.userPackage = userPackage.filter(m => m.id !== payload);
      } else {
        if (userPackage[idx].count <= 1) {
          // 只剩一个就移除
          state.userPackage = userPackage.filter(m => m.id !== payload);
        } else {
          // 否则就减去
          userPackage[idx].count -= 1;
          state.userPackage = userPackage;
        }
      }
    } else {
      console.log("物品不存在");
    }
    const storeData = objEncodeToStr(state.userPackage);
    storage.set(MutationTypes.PUT_ITEM_TO_PACKAGE, storeData);
  },
  [MutationTypes.REMOVE_ITEM_TO_PACKAGE_MUL](state, payload) {
    let userPackage = [...state.userPackage];
    payload.forEach(({ id, count }: { id: number; count: number }) => {
      const idx = userPackage.findIndex(m => m.id === id);
      if (idx >= 0) {
        // 存在
        if (userPackage[idx].type === "equipment") {
          userPackage = userPackage.filter(m => m.id !== id);
        } else {
          const finCount = Math.min(count, userPackage[idx].count);
          userPackage[idx].count -= finCount;
          if (userPackage[idx].count === 0) {
            userPackage = userPackage.filter(m => m.id !== id);
          }
        }
      } else {
        console.log("物品不存在");
      }
    });
    state.userPackage = userPackage;
    const storeData = objEncodeToStr(state.userPackage);
    storage.set(MutationTypes.PUT_ITEM_TO_PACKAGE, storeData);
  },
  [MutationTypes.GET_PACKAGE](state) {
    const storeData = storage.get(MutationTypes.PUT_ITEM_TO_PACKAGE);
    if (storeData) {
      const storeUserPackage = strDecodeToObj(storeData);
      // 将上一个版本的物品遗漏属性填充
      const packageList = storeUserPackage.map((m: Partial<PackItem>) => {
        return new PackItemDTO(m);
      });
      state.userPackage = packageList;
    }
  },
  [MutationTypes.WEAR_EQUIP](state, payload) {
    const userWearableEquipments = {
      ...state.userWearableEquipments
    };
    userWearableEquipments[payload.type] = payload;
    state.userWearableEquipments = userWearableEquipments;
    const storeData = objEncodeToStr(userWearableEquipments);
    storage.set(MutationTypes.WEAR_EQUIP, storeData);
  },
  [MutationTypes.CAST_EQUIP](state, payload) {
    const userWearableEquipments = {
      ...state.userWearableEquipments
    };
    delete userWearableEquipments[payload.type];
    state.userWearableEquipments = userWearableEquipments;
    const storeData = objEncodeToStr(userWearableEquipments);
    storage.set(MutationTypes.WEAR_EQUIP, storeData);
  },
  [MutationTypes.GET_EQUIP](state) {
    const storeData = storage.get(MutationTypes.WEAR_EQUIP);
    if (storeData) {
      const userWearableEquipments = strDecodeToObj(storeData);
      state.userWearableEquipments = userWearableEquipments;
    }
  },
  [MutationTypes.SET_TOWER_LEVEL](state, payload) {
    if (payload.value <= state.userTowerLevel[payload.label]) return;
    state.userTowerLevel[payload.label] = payload.value;
    const storeData = objEncodeToStr(state.userTowerLevel);
    storage.set(MutationTypes.SET_TOWER_LEVEL, storeData);
  },
  [MutationTypes.GET_TOWER_LEVEL](state) {
    const storeData = storage.get(MutationTypes.SET_TOWER_LEVEL);
    if (storeData) {
      const userTowerLevel = strDecodeToObj(storeData);
      state.userTowerLevel = userTowerLevel;
    }
  },
  [MutationTypes.SET_USER_STATE](state, payload) {
    state.userInfo.state = payload;
    const storeData = objEncodeToStr(state.userInfo);
    storage.set(MutationTypes.SET_USER_INFO, storeData);
  },
  [MutationTypes.TIDY_PACKAGE](state) {
    const map = {
      equipment: 1,
      consumables: 0
    };

    state.userPackage
      .sort((a, b) => b.grade - a.grade)
      .sort((a, b) => map[a.type] - map[b.type])
      .sort((a, b) => +b.isLock - +a.isLock);
    const storeData = objEncodeToStr(state.userPackage);
    storage.set(MutationTypes.PUT_ITEM_TO_PACKAGE, storeData);
  }
};
